package search.dynamic;

import java.util.LinkedList;
import java.util.Vector;
import env.Action;
import env.Enviroment;
import env.Orientation;
import env.Tile;
import env.TileType;

public class Planner {

	private int[][] path;
	private Tile[][] pie;
	private Tile src;
	private Enviroment env;
	
	public Planner(Enviroment env, Tile src) {
		this.env = env;
		this.src = src;
		path = new int[env.rows][env.cols];
		pie = new Tile[env.rows][env.cols];
		path[src.getRow()][src.getCol()] = 1;
		findPath(this.src);
		System.out.println("flag "+src.getRow()+","+src.getCol());
		for (int i=0;i<path.length;++i) {
			for (int j=0;j<path[i].length;++j) {
				System.out.print((path[i][j] < 10 ? "0": "") + path[i][j]+" ");
			}
			System.out.println();
		}
		System.out.println("**");
	}
	
	
	public Tile getSrc() {
		return src;
	}


	public int getScore (int row, int col) {
		return this.path[row][col];
	}
	
	public LinkedList<Tile> getRout(int row, int col) {
		LinkedList<Tile> r = new LinkedList<Tile>();
		Tile t = this.src;
		do {
			r.add(t);
			t = this.pie[t.getRow()][t.getCol()];
		} while (t!= null && t.getRow() != row && t.getCol() != col);
		return r;
		
	}
	
	private void findPath(Tile src) {
		LinkedList<Tile> neighbors = getLegalNeighbors(src);
		while (!neighbors.isEmpty()) {
			Tile curr = neighbors.poll();
			if ((path[curr.getRow()][curr.getCol()] == 0 |
				path[curr.getRow()][curr.getCol()] >= path[src.getRow()][src.getCol()] + 1) && 
				isLegalMove(src.getRow(),src.getCol(),curr.getRow(),curr.getCol())) {
				this.path[curr.getRow()][curr.getCol()] = path[src.getRow()][src.getCol()] + 1;
				this.pie[src.getRow()][src.getCol()] = curr;
				findPath(curr);
			}
		}
	}
	
	private LinkedList<Tile> getLegalNeighbors(Tile src) {
		LinkedList<Tile> v = new LinkedList<Tile>();
		int oRow = src.getRow();
		int oCol = src.getCol();
		if (isLegalMove(oRow,oCol,oRow-1,oCol))
			v.add(env.map[oRow-1][oCol]);
		if (isLegalMove(oRow,oCol,oRow+1,oCol))
			v.add(env.map[oRow+1][oCol]);
		if (isLegalMove(oRow,oCol,oRow,oCol-1))
			v.add(env.map[oRow][oCol-1]);
		if (isLegalMove(oRow,oCol,oRow,oCol+1))
			v.add(env.map[oRow][oCol+1]);
		return v;
	}
        
	private boolean isLegalMove(int orow,int ocol,int drow,int dcol) {
        return orow >= 0 && orow < env.rows &&
               ocol >= 0 && ocol < env.cols &&
               drow >= 0 && drow < env.rows &&
               dcol >= 0 && dcol < env.cols &&
        ((ocol == dcol & orow == drow) |(ocol == dcol ^ orow == drow)) &&
            env.map[orow][ocol].getType()!= TileType.wall;
	}
	
    private static Orientation getOrientation(int orow,int ocol,int drow,int dcol) {
    	if (orow == drow) {
    		if (dcol < ocol) {
    			return Orientation.West;
    		}
    		else {
    			return Orientation.East;
    		}
    	}
    	else {
    		if (drow < orow) {
    			return Orientation.North;
    		}
    		else {
    			return Orientation.South;
    		}
    	}
    }
	
}
